package evemanutool.utils.databases; import java.io.FileReader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import au.com.bytecode.opencsv.CSVReader; import evemanutool.constants.DBConstants; import evemanutool.data.database.Blueprint; import evemanutool.data.database.Decryptor; import evemanutool.data.database.Item; import evemanutool.data.database.MarketGroup; import evemanutool.data.database.Material; import evemanutool.data.database.Relic; import evemanutool.gui.main.EMT; import evemanutool.utils.datahandling.Database; import evemanutool.utils.datahandling.DatabaseHandler.Stage; public class BlueprintDB extends Database implements DBConstants { //DB:s private ItemDB idb; private MarketGroupDB mdb; private TechDB tdb; //Data. private volatile HashMap<Integer, Blueprint> dbB; private volatile HashMap<Integer, Blueprint> dbP; //List of market types. private volatile HashSet<Integer> idL; private volatile HashSet<Integer> idSL; //Shorter list. public BlueprintDB() { super(true, false, Stage.DERIVED, Stage.PROCESS); } public void init(ItemDB idb, MarketGroupDB mdb, TechDB tdb) { this.idb = idb; this.mdb = mdb; this.tdb = tdb; } @Override public synchronized void loadDerivedData() throws Exception { //Temporary variables. HashMap<Integer, Blueprint> tmpDbB = new HashMap<Integer, Blueprint>(); HashMap<Integer, Blueprint> tmpDbP = new HashMap<Integer, Blueprint>(); String[] nextLine; Blueprint b; Item i; MarketGroup mg; int id; double tmpValue; //Read the BPO list. CSVReader csv = new CSVReader(new FileReader(BLUEPRINTS_PATH), ';'); //Skip header. csv.readNext(); while ((nextLine = csv.readNext()) != null) { id = Integer.parseInt(nextLine[0]); i = idb.getItem(Integer.parseInt(nextLine[2])); //Only add if the BPO-product and BPO is on market. if (i.isOnMarket()) { //Add to DB. add( new Blueprint( idb.getItem(id), i, Integer.parseInt(nextLine[4]), Integer.parseInt(nextLine[12]), i.getPortionSize(), Integer.parseInt(nextLine[3]), Integer.parseInt(nextLine[11]), Integer.parseInt(nextLine[9]), Integer.parseInt(nextLine[7]) * 2, //Base is only half of max runs. Integer.parseInt(nextLine[8]), Integer.parseInt(nextLine[6]), Integer.parseInt(nextLine[5]), getInventionChance(i, tdb), getRevDecryptor(i, idb)), tmpDbB, tmpDbP); } } csv.close(); //Read the material requirement list. csv = new CSVReader(new FileReader(TYPE_REQUIREMENTS_PATH), ';'); //Skip header. csv.readNext(); while ((nextLine = csv.readNext()) != null) { b = tmpDbB.get(Integer.parseInt(nextLine[0])); //1 == manufacturing. if (b != null) { i = idb.getItem(Integer.parseInt(nextLine[2])); mg = mdb.getParentpByGroup(i.getMarketGroup()); //Skip if item is a skill. if (mg != null && mg.getName().equalsIgnoreCase("skills")) { continue; } if (Integer.parseInt(nextLine[1]) == IndustryActivity.MANUFACTURE.key) { //Add extra material, (Amount = Quantity * Damage_Per_Job). b.getExtraMaterials().add(new Material(i, Integer.parseInt(nextLine[3]) * Double.parseDouble(nextLine[4].replace(',', '.')), Integer.parseInt(nextLine[5]) == 1)); }else if (Integer.parseInt(nextLine[1]) == IndustryActivity.INVENTION.key) { tmpValue = Integer.parseInt(nextLine[3]) * Double.parseDouble(nextLine[4].replace(',', '.')); //If interface, add decryptors and set amount to 0. if (i.getItemGroup() == DATA_INTERFACES_GROUP) { b.getInvDecryptors().addAll(tdb.getDecryptorsFromInterface(i.getTypeId())); tmpValue = 0; } //Add to invention list. (Set amounts for Interfaces to 0, (base amount: 1)) b.getInvMaterials().add(new Material(i, tmpValue)); } } } csv.close(); //Add revRelics to T3 blueprints. for (Blueprint bP : tmpDbB.values()) { if (bP.getTechLevel() == 3) { bP.getRevRelics().addAll(tdb.getRevRelicsFromProduct(bP.getProduct())); } } //Check for BPO:s with non accessible items and add all approved to query list. ArrayList<Blueprint> removeList = new ArrayList<>(); HashSet<Integer> tmpIdL = new HashSet<>(); HashSet<Integer> tmpIdSL = new HashSet<>(); for (Blueprint bl : tmpDbB.values()) { if (hasNonMarketMaterials(bl.getExtraMaterials()) || hasNonMarketMaterials(bl.getProduct().getBaseMaterials())) { removeList.add(bl); } else { //Add to market query id:s. tmpIdL.add(bl.getProduct().getTypeId()); tmpIdSL.add(bl.getProduct().getTypeId()); //Add BPO if on market. if (bl.getBlueprintItem().isOnMarket()) { tmpIdL.add(bl.getBlueprintItem().getTypeId()); } for (Material m : bl.getExtraMaterials()) { tmpIdL.add(m.getItem().getTypeId()); tmpIdSL.add(m.getItem().getTypeId()); } for (Material m : bl.getProduct().getBaseMaterials()) { tmpIdL.add(m.getItem().getTypeId()); tmpIdSL.add(m.getItem().getTypeId()); } //If blueprint can be invented add materials and decryptors. if (bl.getInvMaterials().size() > 0) { for (Material m : bl.getInvMaterials()) { tmpIdL.add(m.getItem().getTypeId()); tmpIdSL.add(m.getItem().getTypeId()); } for (Decryptor d : bl.getInvDecryptors()) { tmpIdL.add(d.getDecryptor().getTypeId()); tmpIdSL.add(d.getDecryptor().getTypeId()); } for (Item item : tdb.getT1Items(bl.getProduct().getTypeId())) { tmpIdL.add(item.getTypeId()); tmpIdSL.add(item.getTypeId()); } } //If blueprint can be reverse engineered add materials. if (bl.getRevDecryptor() != null && bl.getRevRelics().size() > 0) { tmpIdL.add(bl.getRevDecryptor().getTypeId()); tmpIdSL.add(bl.getRevDecryptor().getTypeId()); for (Relic rel : bl.getRevRelics()) { tmpIdL.add(rel.getRelic().getTypeId()); tmpIdSL.add(rel.getRelic().getTypeId()); for (Material m : rel.getRevMaterials()) { tmpIdL.add(m.getItem().getTypeId()); tmpIdSL.add(m.getItem().getTypeId()); } } } } } //Remove invalid blueprints. for (Blueprint blueprint : removeList) { remove(blueprint, tmpDbB, tmpDbP); } //Set new database to global reference. dbB = tmpDbB; dbP = tmpDbP; idL = tmpIdL; idSL = tmpIdSL; //Show message. EMT.M_HANDLER.addMessage("Blueprint data collected and merged."); //Last initiation step, set complete. super.setComplete(true); } private Item getRevDecryptor(Item i, ItemDB idb) { for (Item dec : idb.getItemsInGroup(REV_DECRYPTOR_GROUP_ID)) { if (dec.getRaceId() == i.getRaceId()) { return dec; } } return null; } private double getInventionChance(Item product, TechDB tdb) { Integer id = product.getItemGroup(); if (Arrays.asList(INV_20_CHANCE_MODGROUPS).contains(id) || product.getTypeId() == INV_20_CHANCE_MODID) { return 0.20; } else if (Arrays.asList(INV_25_CHANCE_MODGROUPS).contains(id) || product.getTypeId() == INV_25_CHANCE_MODID) { return 0.25; } else if (Arrays.asList(INV_30_CHANCE_MODGROUPS).contains(id) || product.getTypeId() == INV_30_CHANCE_MODID){ return 0.30; } else if (tdb.getT2Item(product.getTypeId()) != null){ return 0.40; } return 0.0; } private boolean hasNonMarketMaterials(Collection<Material> mL) { for (Material m : mL) { if (!m.getItem().isOnMarket()) { return true; } } return false; } private void remove(Blueprint b, HashMap<Integer, Blueprint> dbB, HashMap<Integer, Blueprint> dbP) { dbB.remove(b.getBlueprintItem().getTypeId()); dbP.remove(b.getProduct().getTypeId()); } private void add(Blueprint b, HashMap<Integer, Blueprint> dbB, HashMap<Integer, Blueprint> dbP) { dbB.put(b.getBlueprintItem().getTypeId(), b); dbP.put(b.getProduct().getTypeId(), b); } private Blueprint getByBpId(Integer typeId) { return dbB.get(typeId); } private Blueprint getByPrId(Integer typeId) { return dbP.get(typeId); } public Blueprint getByBlueprintId(Integer typeId) { if (dbB.containsKey(typeId)) { return new Blueprint(getByBpId(typeId)); } return null; } public Blueprint getByProductId(Integer typeId) { if (dbP.containsKey(typeId)) { return new Blueprint(getByPrId(typeId)); } return null; } public ArrayList<Integer> getMinMarketQueryIds() { return new ArrayList<>(idSL); } public ArrayList<Integer> getMarketQueryIds() { return new ArrayList<>(idL); } public ArrayList<Blueprint> getCompleteList() { //Copies the HashMap to a separate array. ArrayList<Blueprint> ba = new ArrayList<>(dbB.size()); for (Blueprint b : dbB.values()) { ba.add(new Blueprint(b)); } return ba; } }